﻿using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using DAL;

namespace BLL
{
    public class Map
    {
        public List<BatteryCenter> Stations { get; set; }

        public Map()
        {
            Stations = new List<BatteryCenter>();
        }

        public bool IsEmpty()
        {
            return Stations.Count == 0;
        }

        public void AddStation(BatteryCenter station)
        {
            if (!Stations.Contains(station))
                Stations.Add(station);
        }

        public void AddEdge(BatteryCenter from, BatteryCenter to, double distance)
        {
            if (FindEdge(from, to) == null)
                from.AddEdge(to, distance, true);
        }

        public bool ContainsStation(BatteryCenter station)
        {
            return Stations.Contains(station);
        }

        public bool IsAdjacent(BatteryCenter startStation, BatteryCenter endStation)
        {
            return (FindEdge(startStation, endStation) != null);
        }

        public IEnumerator<BatteryCenter> BatteryStations()
        {
            return Stations.GetEnumerator();
        }

        public IList<Edge> GetAllEdges()
        {
            List<Edge> edgeList = new List<Edge>();

            foreach (BatteryCenter bs in Stations)
                edgeList.AddRange(bs.Edgelist);

            return edgeList;
        }

        public IList<BatteryCenter> GetAdjacencies(BatteryCenter station)
        {
            IList<BatteryCenter> adjStations = new List<BatteryCenter>();
            IEnumerator ien = station.Edgelist.GetEnumerator();

            while (ien.MoveNext())
            {
                Edge e = (Edge)ien.Current;
                adjStations.Add((BatteryCenter)e.BatteryStation1);
            }

            return adjStations;
        }

        public int GetNoOfStations()
        {
            return Stations.Count();
        }

        public int GetNoOfEdges()
        {
            int noOfEdges = 0;

            foreach (BatteryCenter station in Stations)
                noOfEdges += station.OutDegree();

            return noOfEdges;
        }

        public void Clear()
        {
            Stations.Clear();
        }

        public Edge FindEdge(BatteryCenter from, BatteryCenter to)
        {
            Edge edge = null;

            foreach (var e in from.Edgelist)
            {
                if (e.BatteryStation1.name.Equals(to.name))
                    edge = e;
            }

            return edge;
        }

        public void RemoveEdge(BatteryCenter from, BatteryCenter to)
        {
            Edge e_from = FindEdge(from, to);
            Edge e_to = FindEdge(to, from);

            if (e_from != null)
            {
                BatteryCenter bc = (BatteryCenter)e_from.BatteryStation1;
                bc.RemoveEdge(e_from);
            }

            if (e_to != null)
            {
                BatteryCenter bc = (BatteryCenter)e_to.BatteryStation1;
                bc.RemoveEdge(e_to);
            }
        }

        public void RemoveBatteryStation(BatteryCenter station)
        {
            Stations.Remove(station);

            IList<BatteryCenter> adjList = GetAdjacencies(station);

            foreach (BatteryCenter bs_adj in adjList)
                RemoveEdge(station, bs_adj);
        }

        public void UnmarkAll()
        {
            foreach (BatteryCenter bs in Stations)
                bs.Mark = false;
        }
    }
}